/*
 * @Author: ipk518 121206530@qq.com
 * @Date: 2023-11-20 09:00:51
 * @LastEditors: ipk518 121206530@qq.com
 * @LastEditTime: 2024-03-08 16:42:36
 * @FilePath: /moduleTest/src/main.c
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include "main.h"
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

#include <termios.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
#include <signal.h>

#include "myLog.h"

#include "csi.h"
#include "gpio.h"
#include "mem.h"
#include "spi.h"
#include "uart.h"
#include "irq.h"

typedef struct {
    uint32_t fileLoad;
    const char *filename;
} fileConf;

enum workType {
    runLed,
    runMem,
    runSpi1,
    runSpi2,
    runCsi,
    runIrq,
    runIdle,
    runStop,
}workt;

fileConf filePath[]={
    {0,  "conf/mylog.conf"},
    {1 , "mylog.conf"},
};


/* Exit flag */
volatile bool g_quit = false;

static int dataLen = 2048;
static int speed = 5000000;
static int addr = 0x60000000;
static uint32_t ww = 1024;
static uint32_t hh = 512;
static uint32_t nn = 100;
static uint32_t value = 0;
int m_val[2]={0,0};
static int gpioValue = 0;
static int irqMode = 0;


void sig_handle(int arg) {
    g_quit = true;
}

// R_OK：可读
// W_OK：可写
// X_OK：可执行
// F_OK：文件存在
int isFileExist(const char* pName)
{
    return (0 == access(pName, F_OK));
}



void *work(void *argc)
{
    while(*(int *)argc != runStop)
    {
        switch (*(int *)argc)
        {
        case runLed:
            controlLed();
            break;
        case runMem:
            qlog_i("----------------------ddr-------------------");
            qlog_w("ddr test start");
            m_val[0] = memOut32(addr);
            memIn32(addr,value);
            m_val[1] = memOut32(addr);
            qlog_w("writeValue:%d, oldValue:%d, newValue:%d",value,m_val[0],m_val[1]);
            *(int *)argc = runIdle;
            qlog_i("--------------------------------------------");
            break;
        case runSpi1:
            qlog_i("--------------------spi1---------------------");
            qlog_w("single spi test start");
            spiTest(1,dataLen,speed);
            *(int *)argc = runIdle;
            qlog_i("--------------------------------------------");
            break;
        case runSpi2:
            qlog_i("---------------------spi2--------------------");
            qlog_w("dual spi test start");
            spiTest(2,dataLen,speed);
            *(int *)argc = runIdle;
            qlog_i("--------------------------------------------");
            break;
        case runCsi:
            qlog_i("--------------------csi---------------------");
            qlog_w("csi test start");
            csiInit(ww,hh,nn);
            *(int *)argc = runIdle;
            qlog_i("--------------------------------------------");
            break;
        case runIrq:
            qlog_i("--------------------irq---------------------");
            qlog_w("irq test start");
            if (irqMode == 0) {
                fpgaIntc(gpioValue);
            } else {
                fgpaPoll(gpioValue);
            }
            *(int *)argc = runIdle;
            qlog_i("--------------------------------------------");
            break;
        case runIdle:
            usleep(10000);
            break;
        default:
            usleep(10000);
            break;
        }
        sleep(1);
    }
}

int main(int argc,char **argv)
{
    bool found,ret = true;
    int i = 0;
    /* Ctrl+c handler */
    signal(SIGINT, sig_handle);
    enum workType m_work = runIdle;
    for (i = 0; i < ARRAY_SIZE(filePath); i++) {
        found = isFileExist(filePath[i].filename);
        if (found) {
            ret = my_logInit(filePath[i].filename);
        }
        if (0 != ret) {
            fprintf(stderr, "init log with configuration file '%s' failed.\n", filePath[i].filename);
        } else {
            qlog_i("logger init done('%s').", filePath[i].filename);
            break;
        }
    }
    
    bool workFlag= true;
    pthread_t tidWork;
    i = pthread_create(&tidWork,NULL,work,(void *)&m_work);//创建线程
    char str[64];
    uartInit();//初始化串口
    qlog_i("please enter  \"led/spi1/csi/ddr/irq/stop\":");
    do {
        i = scanf("%s", str);
        if ( strcmp(str,"led") == 0 ) {
            qlog_w("Run led test!");
            m_work = runLed;
        }
        if (strcmp(str,"spi1") == 0) {
            qlog_w("Run spi single test!");
            qlog_i("please enter  \"spi speed (K)\":");
            i = scanf("%s", str);
            speed = atoi(str);
            qlog_i("please enter  \"spi transfer size (KB)\":");
            i = scanf("%s", str);
            dataLen = atoi(str);
            qlog_w("spi1 speed: %dK,data size: %dKB",speed,dataLen);
            if(speed == 0 || dataLen == 0) {
                qlog_e("Enter data error");
            }else{
                m_work = runSpi1;
            }
        }
        if (strcmp(str,"spi2") == 0) {
            qlog_w("Run spi dual test!");
            qlog_i("please enter  \"spi speed (K)\":");
            i = scanf("%s", str);
            speed = atoi(str);
            qlog_i("please enter  \"spi transfer size (KB)\":");
            i = scanf("%s", str);
            dataLen = atoi(str);
            qlog_w("spi2 speed: %dK,data size: %dKB",speed,dataLen);
            if(speed == 0 || dataLen == 0) {
                qlog_e("Enter data error");
            }else{
                m_work = runSpi2;
            }
            
        }
        if (strcmp(str,"csi") == 0) {
            qlog_w("Run csi test!");
            qlog_i("please enter  \"csi width (than 32)\":");
            i = scanf("%s", str);
            ww = atoi(str);
            qlog_i("please enter  \"csi height (than 32)\":");
            i = scanf("%s", str);
            hh = atoi(str);
            qlog_i("please enter  \"csi number (than 1)\":");
            i = scanf("%s", str);
            nn = atoi(str);
            if(nn < 1 || ww < 1 || hh < 1) {
                qlog_e("Enter csi data error");
            } else {
                m_work = runCsi;
            }
        }
        if (strcmp(str,"ddr") == 0) {
            qlog_w("Run ddr test!");
    
            qlog_i("please enter hex \"ddr read/write address (defaut:0x30000000,0x30000000~0x40000000)\":");
            i = scanf("%s", str);
            // addr = atoi(&str);
            addr = strtoul(&str, 0, 0);
            if(addr == 0) {
                qlog_i("please enter  \"ddr read/write address (805306368(0x30000000)~1073741824(0x40000000))\":");
                i = scanf("%s", str);
                // addr = atoi(&str);
                addr = strtoul(&str, 0, 0);
            }
            if(addr == 0) {
                qlog_e("addr error:%#x,set defaut:0x30000000.",addr);
                addr = 0x30000000;
            }
            qlog_i("please enter  \"ddr read/write value (int)\":");
            i = scanf("%s", str);
            value = atoi(str);
            qlog_w("ddr read/write address:%#x,value:%d",addr,value);
            m_work = runMem;
            
        }
        if (strcmp(str,"irq") == 0) {
            qlog_w("Run irq test!");
            qlog_i("please enter \"trigger gpio(227)\":");
            i = scanf("%s", str);
            gpioValue = atoi(&str);
            qlog_i("please enter \"trigger mode \"irq(0) and poll(1)\"\":");
            i = scanf("%s", str);
            irqMode = atoi(&str);
            if(gpioValue > 1) {
                qlog_w("irq trigger gpio%d run",gpioValue);
                m_work = runIrq;
            }
        }
        if (strcmp(str,"q") == 0) {
            qlog_w("Stop all test task!");
            m_work = runStop;
            break;
        }
        if (strcmp(str,"stop") == 0) {
            qlog_w("Stop all test task!");
            m_work = runStop;
            break;
        }
        
        qlog_i("Old command %s,please enter \"led/spi1/csi/ddr/irq/stop\":",str);
        memset(str,0,sizeof(str));
    } while(1);
        
    return 0;
}